import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.chat.*;
import net.minecraft.server.v1_16_R3.EntityPlayer;
import net.minecraft.server.v1_16_R3.VillagerType;
import org.bukkit.*;
import org.bukkit.attribute.Attribute;
import org.bukkit.attribute.AttributeInstance;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.PistonMoveReaction;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftHumanEntity;
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.*;
import org.bukkit.entity.memory.MemoryKey;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.inventory.*;
import org.bukkit.metadata.MetadataValue;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionAttachment;
import org.bukkit.permissions.PermissionAttachmentInfo;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.plugin.Plugin;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.scoreboard.Team;
import org.bukkit.util.BoundingBox;
import org.bukkit.util.RayTraceResult;
import org.bukkit.util.Vector;
import redis.clients.jedis.Jedis;

import java.util.*;

public class Executor {
    private FileConfiguration config = Bukkit.getPluginManager().getPlugin("RedenTreasure").getConfig();

    public void test(CommandSender sender, String[] args) {
        sender.sendMessage("Color: §00§11§22§33§44§55§6§77§88§99§aa§bb§cc§dd§ee§ff");//§ Alt0167
    }

    public void help(CommandSender sender, String[] args) {
        sender.sendMessage(config.getStringList("help.content").toArray(new String[]{}));
    }

    public void menu(CommandSender sender, String[] args) {
        if (!(sender instanceof Player))
            return;
        Player player = (Player) sender;
        Integer size = config.getInt("menu.size") * 9;
        Inventory inventory = Bukkit.createInventory(null, size, "主菜单");
        for (int i = 0; i < size; i++) {
            String key = "menu.item." + i;
            ItemStack temp = Nms.item(new HashMap() {{
                put("Tag", "MenuItem");
                if (config.contains(key)) {
                    if (config.contains(key + ".type"))
                        put("Type", config.getString(key + ".type"));
                    if (config.contains(key + ".name"))
                        put("Name", config.getString(key + ".name"));
                    if (config.contains(key + ".lore"))
                        put("Lore", config.getStringList(key + ".lore"));
                    if (config.contains(key + ".left"))
                        put("Left", config.getString(key + ".left"));
                    if (config.contains(key + ".right"))
                        put("Right", config.getString(key + ".right"));
                    if (config.contains(key + ".leftS"))
                        put("LeftS", config.getString(key + ".leftS"));
                    if (config.contains(key + ".rightS"))
                        put("RightS", config.getString(key + ".rightS"));
                }
            }});
            inventory.setItem(i, temp);
        }
        player.openInventory(inventory);
    }

    public void team(CommandSender sender, String[] args) {
        try {
            String cmd = args[0];
            String name = args[1];
            switch (cmd) {
                case "info":
                    RedisInstance.getInstance().getTeam(name);
                    break;
                case "list":
                    for (Team team : Bukkit.getScoreboardManager().getMainScoreboard().getTeams()) {
                        sender.sendMessage(team.getDisplayName());
                    }
                    break;
                case "create":
                    if (Bukkit.getScoreboardManager().getMainScoreboard().getTeam(name) == null) {
                        Bukkit.getScoreboardManager().getMainScoreboard().registerNewTeam(name);
                    }
                    break;
                case "delete":
                    Team team = Bukkit.getScoreboardManager().getMainScoreboard().getTeam(name);
                    if (team == null) {
                        Bukkit.getScoreboardManager().getMainScoreboard().getTeams().remove(team);
                    }
                    break;
                default:
                    return;
            }
            /*

            */
        } catch (Exception e) {
            sender.sendMessage("§4Team指令执行异常");
        }

    }

    public void quest(CommandSender sender, String[] args) {
        if (!(sender instanceof Player))
            return;
        Player player = (Player) sender;
        Integer size = config.getInt("quest.size") * 9;
        Inventory inventory = Bukkit.createInventory(null, size, "兑换区");
        for (int i = 0; i < size; i++) {
            String key = "quest.item." + i;
            ItemStack temp = Nms.item(new HashMap() {{
                put("Tag", "QuestItem");
                if (config.contains(key)) {
                    if (config.contains(key + ".type"))
                        put("Type", config.getString(key + ".type"));
                    if (config.contains(key + ".name"))
                        put("Name", config.getString(key + ".name"));
                    if (config.contains(key + ".lore"))
                        put("Lore", config.getStringList(key + ".lore"));
                    if (config.contains(key + ".factor"))
                        put("Factor", config.getString(key + ".factor"));
                    if (config.contains(key + ".reward"))
                        put("Reward", config.getString(key + ".reward"));
                }
            }});
            inventory.setItem(i, temp);
        }
        player.openInventory(inventory);

    }

    public void enderchest(CommandSender sender, String[] args) {
        if (!(sender instanceof Player))
            return;
        Player player = (Player) sender;
        if (args.length > 1 && sender.isOp())
            player = Bukkit.getPlayerExact(args[1]);
        if (player != null)
            ((Player) sender).openInventory(player.getEnderChest());
    }

    public void invsee(CommandSender sender, String[] args) {
        if (!(sender instanceof Player))
            return;
        if (sender.isOp() && args.length > 1) {
            Player player = (Player) Bukkit.getPlayerExact(args[1]);
            if (player != null)
                ((Player) sender).openInventory(player.getInventory());
        }
    }


    public void back(CommandSender sender, String[] args) {
        if (!(sender instanceof Player))
            return;
        Player player = (Player) sender;
        String result = RedisInstance.getInstance().getBack(player.getName());
        Location location = player.getLocation();
        location.setWorld(Bukkit.getWorld(result.split(",")[0]));
        location.setX(Double.valueOf(result.split(",")[1]));
        location.setY(Double.valueOf(result.split(",")[2]));
        location.setZ(Double.valueOf(result.split(",")[3]));
        if (location != null) {
            player.teleport(location);
            RedisInstance.getInstance().delBack(player.getName());
        } else {
            player.sendMessage("§4传送失败，未查询到死亡坐标或已消耗back机会");
        }
    }

    public void home(CommandSender sender, String[] args) {
        if (!(sender instanceof Player))
            return;
        Player player = (Player) sender;
        String result = RedisInstance.getInstance().getHome(player.getName());
        if (result != null) {
            Location location = player.getLocation();
            location.setWorld(Bukkit.getWorld(result.split(",")[0]));
            location.setX(Double.valueOf(result.split(",")[1]));
            location.setY(Double.valueOf(result.split(",")[2]));
            location.setZ(Double.valueOf(result.split(",")[3]));
            player.teleport(location);
            player.sendMessage("§e传送成功");
        } else {
            player.teleport(Bukkit.getWorld("world").getSpawnLocation());
            player.sendMessage("§e传送失败，未查询到家坐标，回到世界出生点");
        }
    }

    public void sethome(CommandSender sender, String[] args) {
        if (!(sender instanceof Player))
            return;
        Player player = (Player) sender;
        RedisInstance.getInstance().setHome(player.getName());
        player.sendMessage("§e设置成功");
    }

    public void delhome(CommandSender sender, String[] args) {
        if (!(sender instanceof Player))
            return;
        Player player = (Player) sender;
        RedisInstance.getInstance().delHome(player.getName());
        player.sendMessage("§e删除成功");
    }

    public void spawn(CommandSender sender, String[] args) {
        if (!(sender instanceof Player))
            return;
        Player player = (Player) sender;
        Location location = player.getBedSpawnLocation();
        if (location != null) {
            player.teleport(location);
            player.sendMessage("§e传送成功");
        } else {
            player.teleport(Bukkit.getWorld("world").getSpawnLocation());
            player.sendMessage("§e传送失败，床丢失或被阻挡，回到世界出生点");
        }
    }

    public void worldspawn(CommandSender sender, String[] args) {
        if (!(sender instanceof Player))
            return;
        Player player = (Player) sender;
        player.teleport(Bukkit.getWorld("world").getSpawnLocation());
    }

    public void suicide(CommandSender sender, String[] args) {
        if (!(sender instanceof Player))
            return;
        Player player = (Player) sender;
        player.setHealth(0);
    }

    public void position(CommandSender sender, String[] args) {
        Player player = null;
        if (args.length < 3 && sender instanceof Player) {
            player = (Player) sender;
        }
        if (args.length > 2) {
            if (sender.isOp()) {
                player = Bukkit.getPlayerExact(args[2]);
                if (player == null) {
                    sender.sendMessage("§4目标玩家不存在");
                    return;
                }
            }
        }
        Location location = player.getLocation();
        if ((args.length == 1 && sender instanceof Player) || (args.length > 1 && args[1].equalsIgnoreCase("get"))) {
            sender.sendMessage(
                    new String[]{
                            "§e玩家: §f" + player.getName(),
                            "§e世界: §f" + location.getWorld().getName(),
                            "§e坐标: §f" + (int) location.getX() + " , " + (int) location.getY() + " , " + (int) location.getZ(),
                    });
        }
        if (args.length > 1 && args[1].equalsIgnoreCase("send")) {
            Bukkit.broadcastMessage(
                    "§e玩家: §f" + player.getName() + "\n" +
                            "§e世界: §f" + location.getWorld().getName() + "\n" +
                            "§e坐标: §f" + (int) location.getX() + " , " + (int) location.getY() + " , " + (int) location.getZ()
            );
        }
    }

    public void clock(CommandSender sender, String[] args) {
        if (args.length > 2 && args[1].equalsIgnoreCase("set") && sender.isOp()) {
            String clock = args[2];
            clock = clock.replaceAll(" ", "").replaceAll("：", ":");
            if (clock.indexOf(":") < 0)
                return;
            while (clock.startsWith("0"))
                clock = clock.replaceFirst("0", "");
            int time = Integer.parseInt(clock.replace(":", ""));
            int h = time / 100 == 24 ? 0 : time / 100;
            int m = time % 100;
            if (h > 24)
                return;
            Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "time set " + (h - 6 > 0 ? (h - 6) * 1000 : (h + 18) * 1000 + m / 0.06));

            sender.sendMessage("§e设置成功");
        }
        int time = Integer.parseInt(String.valueOf(Bukkit.getWorld("world").getTime()));
        int h = time / 1000 + 6 > 23 ? time / 1000 - 18 : time / 1000 + 6;
        Double m = time % 1000 * 0.06;
        Integer hour = (int) (h * 100 + m) / 100;
        Integer minute = (int) (h * 100 + m) % 100;
        sender.sendMessage("§e当前时间: §f" + (hour < 10 ? "0" + hour : "" + hour) + ":" + (minute < 10 ? "0" + minute : "" + minute));
    }

    public void workbench(CommandSender sender, String[] args) {
        if (!(sender instanceof Player))
            return;
        Player player = (Player) sender;
        player.openWorkbench(null, true);
    }

    public void tpapply(CommandSender sender, String[] args) {
        if (!(sender instanceof Player))
            return;
        Player player = (Player) sender;
        if (args.length < 2) {
            sender.sendMessage("§4请输入目标玩家ID");
            return;
        }
        Player target = Bukkit.getPlayerExact(args[1]);
        if (target == null) {
            sender.sendMessage("§4目标玩家不存在");
            return;
        }
        RedisInstance.getInstance().setApply(player.getName(), target.getName());
        sender.sendMessage("§e发送传送申请成功，请等待玩家响应");

        TextComponent accept = new TextComponent("§f[§a接受§f]");
        TextComponent deny = new TextComponent("§f[§4拒绝§f]");
        accept.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder("§e点击接受传送申请").create()));
        accept.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/rt tpaccept"));
        deny.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder("§4点击拒绝传送申请").create()));
        deny.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/rt tpdeny"));
        TextComponent message = new TextComponent("§f" + player.getName() + " §e申请传送到你的位置 ");
        message.addExtra(accept);
        message.addExtra(new TextComponent("§f | "));
        message.addExtra(deny);
        target.spigot().sendMessage(message);
    }

    public void tpaccept(CommandSender sender, String[] args) {
        if (!(sender instanceof Player))
            return;
        Player player = (Player) sender;
        Player from = null;
        try {
            from = Bukkit.getPlayerExact(RedisInstance.getInstance().getApply(player.getName()));
        } catch (Exception e) {
        }
        if (from != null) {
            from.teleport(player.getLocation());
            from.sendMessage("§f" + player.getName() + " §e已接受传送申请，传送成功");
            player.sendMessage("§e您已接受传送申请，传送成功");
            RedisInstance.getInstance().delApply(player.getName());
        } else {
            player.sendMessage("§4不存在待处理的传送请求，请于接受到请求的60秒内处理申请");
        }
    }

    public void tpdeny(CommandSender sender, String[] args) {
        if (!(sender instanceof Player))
            return;
        Player player = (Player) sender;
        Player from = null;
        try {
            from = Bukkit.getPlayerExact(RedisInstance.getInstance().getApply(player.getName()));
        } catch (Exception e) {
        }
        if (from != null) {
            from.sendMessage("§f" + player.getName() + " §e已拒绝传送申请，传送失败");
            player.sendMessage("§e您已拒绝传送申请");
            RedisInstance.getInstance().delApply(player.getName());
        } else {
            player.sendMessage("§4不存在待处理的传送请求，请于接受到请求的60秒内处理申请");
        }
    }

    public void nick(CommandSender sender, String[] args) {
        if (!(sender instanceof Player))
            return;
        Player player = (Player) sender;
        if (args.length > 1)
            RedisInstance.getInstance().setNick(player.getName(), args[1]);
        else
            RedisInstance.getInstance().delNick(player.getName());
        player.sendMessage("§e昵称修改成功");
    }

    public void nickclear(CommandSender sender, String[] args) {
        if (!(sender instanceof Player))
            return;
        Player player = (Player) sender;
        RedisInstance.getInstance().delNick(player.getName());
        player.sendMessage("§e昵称删除成功");
    }

    public void prefix(CommandSender sender, String[] args) {
        if (!(sender instanceof Player))
            return;
        Player player = (Player) sender;
        if (args.length > 1)
            RedisInstance.getInstance().setPrefix(player.getName(), args[1]);
        else
            RedisInstance.getInstance().delPrefix(player.getName());
        player.sendMessage("§e称号修改成功");
    }

    public void prefixclear(CommandSender sender, String[] args) {
        if (!(sender instanceof Player))
            return;
        Player player = (Player) sender;
        RedisInstance.getInstance().delPrefix(player.getName());
        player.sendMessage("§e称号删除成功");
    }

}
